﻿using CommonLibrary;
using CommonLibrary.Models;
using CommonSite.Areas.API.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BLToolkit.Data.Linq;
using CommonSite.Common;
using CommonHelper;

namespace CommonSite.Areas.API.Controllers
{
    public class FieldController : BaseAPIController
    {
        public ActionResult Query(string id)
        {
            int formId = CryptHelper.DecryptToInt32(id);
            using (CommonDatabase db = new CommonDatabase())
            {
                var query = (from p in db.wf_Field
                             where p.State == 1 && p.FormId == formId
                             select new Field
                             {
                                 Id = CryptHelper.Encrypt(p.Id),
                                 FieldName = p.Name,
                                 FormId = CryptHelper.Encrypt(p.FormId),
                                 FormName = p.wf_Form.Name,
                                 ControlId = p.ControlId,
                                 ControlType = p.wf_FieldControl.Name,
                                 Nullable = p.Nullable,
                                 Editable = p.Editable,
                                 Source = p.Source,
                                 DefaultValue = p.DefaultValue,
                                 Argument = p.Argument
                             }).ToList();

                return Success(new
                {
                    Total = query.Count,
                    Rows = query
                });
            }
        }

        public ActionResult Create(Field field)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                    {
                        db.BeginTransaction();
                        int formId = CryptHelper.DecryptToInt32(field.FormId);
                        if (db.wf_Field.Where(k => k.Name == field.FieldName &&
                                                   k.State == 1 &&
                                                   k.FormId == formId).Count() > 0)
                            throw new ArgumentException("字段名不能重复");

                        CheckField(field);

                        // 如果控件式表格控件，那么首先添加表格数据，修改Source为表格ID
                        if (field.ControlId == 10)
                        {
                            field.Source = this.InitTableData(db, field.Argument);
                            field.Argument = "";
                        }

                        db.wf_Field.Insert(() => new wf_Field
                        {
                            FormId = formId,
                            Name = field.FieldName,
                            ControlId = field.ControlId,
                            Nullable = field.Nullable,
                            Editable = field.Editable,
                            Source = field.Source,
                            DefaultValue = field.DefaultValue,
                            Argument = field.Argument
                        });

                        db.SetCommand(
                            "update wf_Form set Version = Version + 1 where Id = @id",
                            db.Parameter("@id", formId))
                          .ExecuteNonQuery();

                        db.CommitTransaction();
                        return Success();
                    }
                }
                catch (Exception ex)
                {
                    return Failed(ex.Message);
                }
            }

            return ArgumentFailed();
        }

        public ActionResult Update(Field field)
        {
            if (this.ModelState.IsValid)
            {
                try
                {
                    using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                    {
                        db.BeginTransaction();
                        int id = CryptHelper.DecryptToInt32(field.Id);
                        int formId = CryptHelper.DecryptToInt32(field.FormId);
                        if (db.wf_Field.Where(k => k.Id == id && k.FormId == formId &&
                            k.State == 1).Count() == 0)
                            throw new ArgumentException("参数错误");

                        CheckField(field);

                        db.wf_Field.Where(k => k.Id == id)
                          .Set(k => k.Name, field.FieldName)
                          .Set(k => k.ControlId, field.ControlId)
                          .Set(k => k.Nullable, field.Nullable)
                          .Set(k => k.Editable, field.Editable)
                          .Set(k => k.Source, field.Source)
                          .Set(k => k.DefaultValue, field.DefaultValue)
                          .Set(k => k.Argument, field.Argument)
                          .Update();

                        db.SetCommand(
                            "update wf_Form set Version = Version + 1 where Id = @id",
                            db.Parameter("@id", formId))
                          .ExecuteNonQuery();

                        db.CommitTransaction();
                        return Success();
                    }
                }
                catch (Exception ex)
                {
                    return Failed(ex.Message);
                }
            }

            return ArgumentFailed();
        }

        public ActionResult Delete(Field field)
        {
            try
            {
                using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                {
                    db.BeginTransaction();
                    int id = CryptHelper.DecryptToInt32(field.Id);
                    db.wf_Field.Where(k => k.Id == id)
                      .Set(k => k.State, 0)
                      .Update();

                    db.CommitTransaction();
                    return Success();
                }
            }
            catch (Exception ex)
            {
                return Failed(ex.Message);
            }
        }

        private void CheckField(Field field)
        {
            switch (field.ControlId)
            {
                case 4:
                case 10:
                    if (field.Argument.IsNullOrWhiteSpace())
                    {
                        throw new ArgumentException("数据来源不能为空");
                    }

                    break;

                default:
                    break;
            }
        }

        private int InitTableData(CommonDatabase db, string arg)
        {
            var list = JSON.ToObject<List<Column>>(arg);
            if (list == null || list.Count == 0)
                throw new ArgumentException("参数错误");

            var table = new wf_Table();
            table.Id = Convert.ToInt32(db.InsertWithIdentity(table));

            var columns = new List<wf_Column>();
            foreach (var item in list)
            {
                columns.Add(new wf_Column
                {
                    ColumnName = item.Name,
                    Nullable = item.Nullable,
                    ControlId = item.ControlId,
                    Argument = item.Argument,
                    DefaultValue = item.DefaultValue,
                    Source = 0,
                    TableId = table.Id,                    
                });
            }

            db.InsertBatch<wf_Column>(columns);
            return table.Id;
        }
    }
}
